package cw.itsource.queue;

import com.rabbitmq.client.*;
import cw.itsource.utils.ConnectionUtil;

import java.io.IOException;

/**
 * 编写消费者的示例代码
 */
public class MainConsumer {
    private static final String QUEUE = "hello-queue";

    public static void main(String[] args) throws Exception {
        //1. 创建一个连接
        Connection connection = ConnectionUtil.getConnection();
        //2. 获取一个通道
        final Channel channel = connection.createChannel();
        //3. 创建一个消费者
        DefaultConsumer defaultConsumer = new DefaultConsumer(channel) {
            /**
             * 消费者接收消息调用此方法
             * @param consumerTag 消费者的标签，在channel.basicConsume()去指定
             * @param envelope 消息包的内容，可从中获取消息id，消息routingkey，交换机，消息和重传标志
            (收到消息失败后是否需要重新发送)
             * @param properties
             * @param body
             */

            @Override //这个方法，就是用于监听通道，并处理通道中的消息（自动处理）
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                String message = new String(body, "utf8"); //将字节数组转为字符串

                System.out.println(">>>>>>>>>>>>>>>消费者接收到的消息内容是：" + message);

                //TODO 进行业务逻辑的处理
                long deliveryTag = envelope.getDeliveryTag();
                System.out.println(deliveryTag);


                //如果代码能执行到  ACK手动确认这一行，说明 业务逻辑处理的代码，正常执行了！！！
                // 当业务逻辑全部成功处理后，可以进行  手动ACK确认
         //注意：如果手动ACK确认。这行确认的代码，通常都是写在方法的最后一行
                channel.basicAck(deliveryTag, false);
            }
        };
        //4. 将消费者绑定到队列上
        /**
         * 监听队列String queue, boolean autoAck,Consumer callback
         * 参数明细
         * 1、队列名称
         * 2、是否自动回复，设置为true为表示消息接收到自动向mq回复接收到了，mq接收到回复会删除消息，设置
         为false则需要手动回复。  参数值为true:自动确认；false:手动确认（ACK机制）
         * 3、消费消息的方法，消费者接收到消息后调用此方法
         */
        channel.basicConsume(QUEUE, false, defaultConsumer); //当代码执行到这一行，即表示消费者已经处理【启动】状态


    }
}
